<template>
  <div class="book-selector">
    <!-- 搜索框 -->
    <div class="top-bar">
      <el-input
        v-model="searchText"
        placeholder="搜索书名/编号/拼音"
        clearable
        @input="handleSearch"
        class="search-input"
      />
    </div>

    <div class="body-wrapper">
      <!-- 左侧导航 -->
      <div class="alpha-nav">
        <div
          v-for="alpha in sortedAlphas"
          :key="alpha"
          class="alpha-item"
          @click="scrollToAlpha(alpha)"
        >
          {{ alpha }}
        </div>
      </div>

      <!-- 右侧书籍 -->
      <div class="books-wrapper" ref="booksWrapper">
        <!-- 不可选书籍 -->
        <div v-if="filteredUnavailableBooks.length" class="unavailable-section">
          <div class="alpha-title">不可选书籍</div>
          <div
            v-for="book in filteredUnavailableBooks"
            :key="book.id"
            class="unavailable-book"
          >
            {{ book.name }} ({{ book.number }})
            <span v-if="book.isExist === 1" class="status lost">已丢失</span>
            <span v-else-if="book.isBorrow === 1" class="status borrowed">已借出</span>
          </div>
        </div>

        <!-- 可选书籍按首字母分组 -->
        <div
          v-for="alpha in sortedAlphas"
          :key="alpha"
          class="alpha-section"
          :ref="el => sectionRefs[alpha] = el as HTMLElement | null"
        >
          <div class="alpha-title">{{ alpha }}</div>
          <el-checkbox-group v-model="selectedIds">
            <el-checkbox
              v-for="book in booksByAlpha[alpha]"
              :key="book.id"
              :label="book.id"
            >
              {{ book.name }} ({{ book.number }})
            </el-checkbox>
          </el-checkbox-group>
        </div>

        <div v-if="!hasBooksToShow" class="no-results">
          抱歉，未搜索到想阅读的书籍
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch, nextTick } from 'vue'
import type { AdmBookStoreVO } from '@/api/general/administration/book/store/types'

const props = defineProps<{ books: AdmBookStoreVO[]; visible: boolean }>()
const emit = defineEmits<{
  (e: 'update:visible', val: boolean): void
  (e: 'confirm', selectedBooks: {id: string|number, name: string, number: string, bookConcern: string}[]): void
  (e: 'cancel'): void
}>()

const visible = ref(props.visible)
watch(() => props.visible, val => visible.value = val)
watch(visible, val => emit('update:visible', val))

const searchText = ref('')
const selectedIds = ref<(string | number)[]>([])
const selectedBooks = ref<{id: string|number, name: string, number: string, bookConcern: string}[]>([])
const booksWrapper = ref<HTMLElement | null>(null)
const sectionRefs: Record<string, HTMLElement | null> = {}

// 不可选书籍
const unavailableBooks = computed(() =>
  props.books.filter(b => b.isExist === 1 || b.isBorrow === 1)
)

// 可选书籍
const availableBooks = computed(() =>
  props.books.filter(b => b.isExist !== 1 && b.isBorrow !== 1)
)

// 生成拼音首字母缩写
const getPinyinAbbr = (pinyin?: string) => {
  if (!pinyin) return ''
  return pinyin
    .split('')
    .map(char => char[0].toLowerCase())
    .join('')
}

// 搜索过滤不可选书籍
const filteredUnavailableBooks = computed(() =>
  unavailableBooks.value.filter(book => {
    const abbr = getPinyinAbbr(book.pinyin)
    const text = searchText.value.toLowerCase()
    const name = String(book.name ?? '').toLowerCase()
    const number = String(book.number ?? '').toLowerCase()
    const pinyin = String(book.pinyin ?? '').toLowerCase()
    
    return (
      name.includes(text) ||
      number.includes(text) ||
      pinyin.includes(text) ||
      abbr.includes(text)
    )
  })
)

// 搜索过滤可选书籍并按首字母分组
const booksByAlpha = computed(() => {
  const map: Record<string, AdmBookStoreVO[]> = {}
  const text = searchText.value.toLowerCase()

  availableBooks.value.forEach(book => {
    const alpha = book.pinyin?.charAt(0).toUpperCase() || '#'
    const abbr = getPinyinAbbr(book.pinyin)
    const name = String(book.name ?? '').toLowerCase()
    const number = String(book.number ?? '').toLowerCase()
    const pinyin = String(book.pinyin ?? '').toLowerCase()

    if (
      name.includes(text) ||
      number.includes(text) ||
      pinyin.includes(text) ||
      abbr.includes(text)
    ) {
      if (!map[alpha]) map[alpha] = []
      map[alpha].push(book)
    }
  })
  return map
})

const sortedAlphas = computed(() => Object.keys(booksByAlpha.value).sort())
const hasBooksToShow = computed(() =>
  filteredUnavailableBooks.value.length > 0 ||
  Object.keys(booksByAlpha.value).some(alpha => booksByAlpha.value[alpha].length > 0)
)

// watch 更新选中书籍
watch(selectedIds, (ids) => {
  selectedBooks.value = props.books
    .filter(b => ids.includes(b.id))
    .map(b => ({
      id: b.id,
      name: b.name,
      number: b.number,
      bookConcern: b.bookConcern ?? ''
    }))
})

// 确认选择
const confirmSelection = () => {
  emit('confirm', selectedBooks.value)
  emit('update:visible', false)
}
defineExpose({ confirmSelection })

// 滚动导航栏
const scrollToAlpha = async (alpha: string) => {
  await nextTick() // 等待 DOM 渲染
  const el = sectionRefs[alpha]
  const container = booksWrapper.value
  if (!el || !container) return

  // 元素相对容器顶部的位置
  const containerRect = container.getBoundingClientRect()
  const elRect = el.getBoundingClientRect()
  const scrollTop = container.scrollTop + (elRect.top - containerRect.top)

  container.scrollTop = scrollTop
  console.log('滚动到首字母:', alpha, 'scrollTop:', scrollTop)
}

// 空方法
const handleSearch = () => {}
</script>

<style scoped>
.book-selector {
  display: flex;
  flex-direction: column;
  height: 100%;
}
.top-bar {
  position: sticky;
  top: 0;
  z-index: 10;
  background: #fff;
  padding-bottom: 8px;
}
.body-wrapper {
  display: flex;
  flex: 1;
  height: 100%;
  gap: 12px;
}
.alpha-nav {
  width: 30px;
  display: flex;
  flex-direction: column;
  align-items: center;
  position: sticky;
  top: 56px;
  height: calc(100% - 56px);
  overflow-y: auto;
}
.alpha-item {
  padding: 4px 0;
  cursor: pointer;
  font-size: 12px;
  color: #409EFF;
}
.books-wrapper {
  flex: 1;
  overflow-y: auto;
  padding-right: 16px;
  height: 100%;
}
.alpha-section { margin-bottom: 16px; }
.alpha-title { font-weight: bold; color: #409EFF; margin-bottom: 6px; }
.unavailable-section { margin-top: 16px; border-top: 1px solid #ebeef5; padding-top: 8px; }
.unavailable-book { margin: 4px 0; color: #909399; }
.status.lost { color: #f56c6c; margin-left: 4px; }
.status.borrowed { color: #e6a23c; margin-left: 4px; }
.no-results { color: #909399; margin: 12px 0; text-align: center; }
</style>
